<?php
/**
 * Created by 784855684@qq.com.
 * Link: https://github.com/lichtung/wshore
 * User: linzh
 * Date: 7/7/17
 * Time: 8:23 AM
 */
declare(strict_types=1);


namespace application\module\admin\addon;


use application\module\admin\addon\property\model\PropertyModel;
use wshore\core\Redis;
use wshore\throws\DatabaseException;
use wshore\throws\db\RecordNotFoundException;

/**
 * Class Property
 *
 * @method Property getInstance(...$parmams) static
 *
 * @package application\module\admin\addon
 */
class Property extends Addon
{
    protected function getName(): string
    {
        return 'property';
    }

    protected function models(): array
    {
        return [
            PropertyModel::class,
        ];
    }

    protected $properties = null;

    /**
     * 配置立即生效
     * @return bool
     */
    public function effectImmediately(): bool
    {
        $temp = [];
        $properties = $this->getList();
        if ($properties) {
            foreach ($properties as $item) {
                $temp[$item['name']] = $item['value'];
            }
        }
        return Redis::getInstance()->set('l_properties', $temp);
    }

    /**
     * 获取配置
     * @param string $name
     * @param string $replace
     * @return string
     */
    public function get(string $name, $replace = '')
    {
        if (!$this->properties) {
            $this->properties = Redis::getInstance()->getSet('l_properties', function () {
                $temp = [];
                $properties = $this->getList();
                if ($properties) {
                    foreach ($properties as $item) {
                        $temp[$item['name']] = $item['value'];
                    }
                }
                return $temp;
            });
        }
        return $this->properties[$name]??$replace;
    }

    /**
     * @param int $id
     * @return array
     * @throws DatabaseException
     */
    public function getInfo(int $id): array
    {
        $model = $this->getPropertyAR($id);
        return $model->all();
    }

    /**
     * @param null $id
     * @return PropertyModel
     * @throws DatabaseException
     */
    private function getPropertyAR($id = null): PropertyModel
    {
        static $instances = [];
        if (!isset($id)) {
            return new PropertyModel();
        }

        if (!isset($instances[$id])) {
            $instances[$id] = new PropertyModel($id);
        }
        return $instances[$id];
    }

    /**
     * @return array
     * @throws DatabaseException
     */
    public function getList(): array
    {
        $list = $this->getPropertyAR()->select();
        return $list;
    }

    /**
     * @param $name
     * @param $value
     * @return bool
     * @throws DatabaseException
     */
    public function set($name, $value): bool
    {
        try {
            $model = new PropertyModel($name);
            $model->value = $value;
        } catch (RecordNotFoundException $exception) {
            $model = new PropertyModel();
            $model->name = $name;
            $model->value = $value;
        }
        return $model->save();
    }

    /**
     * @param int $id
     * @return bool
     * @throws DatabaseException
     */
    public function rm(int $id): bool
    {
        $model = $this->getPropertyAR($id);
        return $model->remove();
    }

    /**
     * @param int $id
     * @param string|null $value
     * @param string|null $note
     * @return void
     * @throws DatabaseException
     */
    public function upd(int $id, string $value = null, string $note = null)
    {
        $model = $this->getPropertyAR($id);
        isset($value) and $model->value = $value;
        isset($note) and $model->note = $note;
        $model->save(false);
    }

    /**
     * @param string $name
     * @param string $value
     * @param string $note
     * @return void
     * @throws DatabaseException
     */
    public function add(string $name, string $value, string $note = '')
    {
        $model = $this->getPropertyAR();
        $model->name = $name;
        $model->value = $value;
        $model->note = $note;
        $model->save(true);
    }
}